﻿using GN.Pay.TradeChannel.Configure;
using GN.Pay.TradeChannel.YJPay.Request;
using GN.Pay.TradeChannel.YJPay.Response;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GN.Pay.TradeChannel.YJPay
{
    [Serializable]
    public abstract class YJPayServiceBase : ATradeChannel<IDictionary<string, string>>
    {
        protected readonly YJPayConfigure channelConfigure;
        public YJPayServiceBase()
        {
            this.channelConfigure = new YJPayConfigure(this);
        }

        public override ITradeChannelConfigure ChannelConfigure
        {
            get
            {
                return channelConfigure;
            }
        }

        /// <summary>
        /// 获取提供者全称
        /// </summary>
        public sealed override string ChannelProvider
        {
            get
            {
                return "重庆易极付科技有限公司";
            }
        }


        public override Type TradeChannelConfigureInfoType
        {
            get
            {
                return typeof(YJPayConfigureInfo);
            }
        }

        private static IChannel TempChannel = TradeChannelInfo.Create("YJPay", "易极付");


        /// <summary>
        /// 获取付款的订单号
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public static string GetPayOrderNo(IDictionary<string, string> message)
        {
            if (message == null || message.Count == 0)
            {
                return null;
            }
            NotifyResponse response = new NotifyResponse(message);
            var entity = response.ToEntity<PayNotifyEntity>();
            return entity.merchOrderNo;
        }


        /// <summary>
        /// 获取退款批次号
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public static string GetRefundNo(IDictionary<string, string> message)
        {
            if (message == null || message.Count == 0)
            {
                return null;
            }
            NotifyResponse response = new NotifyResponse(message);
            var entity = response.ToEntity<RefundNotifyEntity>();
            return entity.orderNo;
        }

        /// <summary>
        /// 支付通知
        /// </summary>
        /// <param name="sercice"></param>
        /// <param name="message"></param>
        public override void OrderPayNotify(INotifyService sercice, IDictionary<string, string> message)
        {
            var entity = OrderPayNotifyResponse(message);
            if (entity.IsSuccess())
            {
                var result = entity.ToResult(this);
                if (result != null)
                {
                    sercice.OrderPayNotify(result);
                }
            }
        }

        /// <summary>
        /// 同步返回通知
        /// </summary>
        /// <param name="sercice"></param>
        /// <param name="message"></param>
        /// <returns></returns>
        public string ReturnOrderPayNotify(INotifyService sercice, IDictionary<string, string> message)
        {
            var entity = OrderPayNotifyResponse(message);
            if (entity.IsSuccess())
            {
                var result = entity.ToResult(this);
                if (result != null)
                {
                    sercice.OrderPayNotify(result);
                }
                return entity.merchOrderNo;
            }
            return null;
        }

        /// <summary>
        /// 订单付款通知响应
        /// </summary>
        /// <param name="message">消息</param>
        private PayNotifyEntity OrderPayNotifyResponse(IDictionary<string, string> message)
        {
            NotifyResponse response = new NotifyResponse(message);
            if (!response.SignVeryfy(this, this.channelConfigure))
            {
                this.ThrowChannelValidationException("易极付支付通知验签失败");
            }
            try
            {
                var entity = response.ToEntity<PayNotifyEntity>();

                //if (string.IsNullOrWhiteSpace(entity.fastPayStatus))
                //{
                //    this.ThrowChannelValidationException("易极付交易付款通知交易状态为null或空白。");
                //}
                return entity;
            }
            catch (Exception e)
            {
                throw this.ThrowChannelValidationException("易极付支付通知数据格式出错:" + e.Message);
            }
        }


        public override void OrderRefundNotify(INotifyService sercice, IDictionary<string, string> message)
        {
            var entity = OrderRefundNotifyResponse(message);
            if (entity.IsSuccess())
            {
                var result = entity.ToResult(this);
                if (result != null)
                {
                    sercice.OrderRefundNotify(result);
                }
            }
        }

        /// <summary>
        /// 订单付款通知响应
        /// </summary>
        /// <param name="message">消息</param>
        private RefundNotifyEntity OrderRefundNotifyResponse(IDictionary<string, string> message)
        {
            NotifyResponse response = new NotifyResponse(message);
            if (!response.SignVeryfy(this, this.channelConfigure))
            {
                this.ThrowChannelValidationException("易极付退款通知验签失败");
            }
            try
            {
                var entity = response.ToEntity<RefundNotifyEntity>();
                return entity;
            }
            catch (Exception e)
            {
                throw this.ThrowChannelValidationException("易极付退款通知数据格式出错:" + e.Message);
            }
        }

        public override ITradeOrderQueryResult OrderSingleQuery(DateTime queryDate, string orderNo, string tradeNo)
        {
            if (string.IsNullOrWhiteSpace(orderNo))
            {
                TradeChannelExceptionUtils.ThrowClientRequestException(this.ChannelId, "查询订单时，必须提供订单号。");
            }
            var config = this.channelConfigure;
            var request = new QueryRequest(this, config, orderNo);
            var response = request.Build();
            return response.ToResult();
        }

        public override ITradeRefundApplyResult RefundApply(IRefundApplyInfo apply)
        {
            var config = this.channelConfigure;
            var request = RefundRequest.CreateRequest(this, apply, config);
            var response = request.Build(this, config, apply);
            return response.ToResult();
        }

        public sealed override string PayNotifyResponse(bool isSuccess)
        {
            if (isSuccess)
            {
                return "success";
            }
            return "";
        }

        public sealed override string RefundNotifyResponse(bool isSuccess)
        {
            if (isSuccess)
            {
                return "success";
            }
            return "";
        }
    }
}
